﻿/*using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TechCraftEngine;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;

//using TomShane.Neoforce.Controls;

//using System.Drawing;
//using System.Drawing.Imaging;
using System.Diagnostics;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace Blox.States
{
    class ConsoleState : State
    {
#if XBOX
        private const string STARTTEXT = "Console";
#else
        private const string STARTTEXT = "Console";
#endif

        private SpriteBatch _spriteBatch;
        private SpriteFont _spriteFont;
        private Vector2 _startTextPosition;       
        //public TitleState(TechCraftGame1 Game1)
        //    : base(Game1)
        //{
        //}

        public ConsoleState()
        {
            //t = new TextBox(this.Game1);
            //Game1.inputManager = new InputManager(Game1.Services, Game1.Window.Handle);
        }

        public TechCraftGame Game1
        {
            get
            {
                return _game; 
            }
            set 
            {
                _game = value;
                //_game.inputManager = new InputManager(_game.Services, _game.Window.Handle);
            }
        }

        private  System.Drawing.Bitmap MakeSnapshot(IntPtr AppWndHandle,
            bool IsClientWnd, Win32API.WindowShowStyle nCmdShow)
        {
            if (AppWndHandle == IntPtr.Zero || !Win32API.IsWindow(AppWndHandle) ||
                        !Win32API.IsWindowVisible(AppWndHandle))
                return null;
            if (Win32API.IsIconic(AppWndHandle))
                Win32API.ShowWindow(AppWndHandle, nCmdShow);//show it
            if (!Blox.Game.SetForegroundWindow(AppWndHandle))
                return null;//can't bring it to front
            System.Threading.Thread.Sleep(1000);//give it some time to redraw
            Win32API.RECT appRect;
            bool res = IsClientWnd ? Win32API.GetClientRect
                (AppWndHandle, out appRect) : Win32API.GetWindowRect
                (new HandleRef(Game1.Window, AppWndHandle), out appRect);
            //if (!res || appRect.height == 0 || appRect.width == 0)
            //{
            //    return null;//some hidden window
            //}
            // calculate the app rectangle
            if (IsClientWnd)
            {
                Point lt = new Point(appRect.left, appRect.top);
                Point rb = new Point(appRect.right, appRect.bottom);
                System.Drawing.Point lt2 = new System.Drawing.Point();
                System.Drawing.Point rb2 = new System.Drawing.Point();
                lt2.X = lt.X;
                lt2.Y = lt.Y;
                rb2.X = rb.X;
                rb2.Y = rb.Y;


                Win32API.ClientToScreen(AppWndHandle, ref lt2);
                Win32API.ClientToScreen(AppWndHandle, ref rb2);
                appRect.left = lt.X;
                appRect.top = lt.Y;
                appRect.right = rb.X;
                appRect.bottom = rb.Y;
            }
            //Intersect with the Desktop rectangle and get what's visible
            IntPtr DesktopHandle = Win32API.GetDesktopWindow();
            /*Win32API.RECT desktopRect;
            Win32API.GetWindowRect(DesktopHandle, out desktopRect);
            Win32API.RECT visibleRect;
            if (!Win32API.IntersectRect
                (out visibleRect, ref desktopRect, ref appRect))
            {
                visibleRect.bottom = appRect.bottom;
                visibleRect.height = appRect.height;
                visibleRect.left = appRect.left;
                visibleRect.right = appRect.right;
                visibleRect.top = appRect.top;
                visibleRect.width = appRect.width;
                //visibleRect = appRect;
            }
            if (Win32API.IsRectEmpty(ref appRect))
                return null;

            int Width = appRect.width;
            int Height = appRect.height;
            IntPtr hdcTo = IntPtr.Zero;
            IntPtr hdcFrom = IntPtr.Zero;
            IntPtr hBitmap = IntPtr.Zero;
            try
            {
                System.Drawing.Bitmap clsRet = null;

                // get device context of the window...
                hdcFrom = IsClientWnd ? Win32API.GetDC(AppWndHandle) :
                        Win32API.GetWindowDC(AppWndHandle);

                // create dc that we can draw to...
                hdcTo = Win32API.CreateCompatibleDC(hdcFrom);
                hBitmap = Win32API.CreateCompatibleBitmap(hdcFrom, Width, Height);

                //  validate
                if (hBitmap != IntPtr.Zero)
                {
                    // adjust and copy
                    int x = appRect.left < 0 ? -appRect.left : 0;
                    int y = appRect.top < 0 ? -appRect.top : 0;
                    IntPtr hLocalBitmap = Win32API.SelectObject(hdcTo, hBitmap);
                    Win32API.BitBlt(hdcTo, 0, 0, Width, Height,
                        hdcFrom, x, y, Win32API.SRCCOPY);
                    Win32API.SelectObject(hdcTo, hLocalBitmap);
                    //  create bitmap for window image...
                    clsRet = System.Drawing.Image.FromHbitmap(hBitmap);
                }
                return clsRet;
            }
            finally
            {
                //  release the unmanaged resources
                if (hdcFrom != IntPtr.Zero)
                    Win32API.ReleaseDC(AppWndHandle, hdcFrom);
                if (hdcTo != IntPtr.Zero)
                    Win32API.DeleteDC(hdcTo);
                if (hBitmap != IntPtr.Zero)
                    Win32API.DeleteObject(hBitmap);
            }
        }

        private class User32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct Rect
            {
                public int Left;
                public int Top;
                public int Right;
                public int Bottom;
                public int Width;
                public int Height;
            }

            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref Rect rect);
        }

        public static Texture2D GetTexture2DFromBitmap(GraphicsDevice device, System.Drawing.Bitmap bitmap)
        {
            Texture2D tex = new Texture2D(device, bitmap.Width, bitmap.Height, false, SurfaceFormat.Color);

            BitmapData data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bitmap.PixelFormat);

            int bufferSize = data.Height * data.Width;

            //create data buffer 
            byte[] bytes = new byte[bufferSize];

            // copy bitmap data into buffer
            Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);

            // copy our buffer to the texture
            tex.SetData(bytes);

            // unlock the bitmap data
            bitmap.UnlockBits(data);

            return tex;
        }

        //Setting the opacity of the image
        public static System.Drawing.Bitmap SetImgOpacity(System.Drawing.Bitmap bmpPic, float imgOpac)
        {
            //Bitmap bmpPic = new Bitmap(imgPic.Width, imgPic.Height);
            System.Drawing.Graphics gfxPic;

            System.Drawing.Bitmap b = null;

            bop:
            try
            {
                gfxPic = System.Drawing.Graphics.FromImage(bmpPic);
            }
            catch (Exception)
            {
                b = new System.Drawing.Bitmap(bmpPic.Width, bmpPic.Height, PixelFormat.Format32bppArgb);
                System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(b);
                g.DrawImage((System.Drawing.Image)bmpPic, 0, 0);
                gfxPic = System.Drawing.Graphics.FromImage(b);
            }

            ColorMatrix cmxPic = new ColorMatrix();
            cmxPic.Matrix33 = imgOpac;
            ImageAttributes iaPic = new ImageAttributes();
            iaPic.SetColorMatrix(cmxPic, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            gfxPic.DrawImage(bmpPic, new System.Drawing.Rectangle(0, 0, bmpPic.Width, bmpPic.Height), 0, 0, bmpPic.Width, bmpPic.Height, System.Drawing.GraphicsUnit.Pixel, iaPic);
            gfxPic.Dispose();

            return bmpPic;
        }

        Texture2D txtr = null;

        public override void Initialize()
        {
            _spriteBatch = new SpriteBatch(Game1.GraphicsDevice);

            System.Drawing.Bitmap bp = MakeSnapshot(Game1.Window.Handle, true, Win32API.WindowShowStyle.Show);

            bp = SetImgOpacity(bp, 75);

            txtr = GetTexture2DFromBitmap(Game1.GraphicsDevice, bp);

            if (Game1.inputManager == null)
            {
                _game.inputManager = new InputManager(_game.Services, _game.Window.Handle);
            }

            IKeyboard keyboard = Game1.inputManager.GetKeyboard();
            keyboard.CharacterEntered += new Nuclex.Input.Devices.CharacterDelegate(charEntered);

            IGamePad Game1Pad = Game1.inputManager.GetGamePad(PlayerIndex.One);
            Game1Pad.ButtonPressed += new GamePadButtonDelegate(Game1PadButtonPressed);

            dummyRectangle = new Rectangle(25, 25, Game1.GraphicsDevice.Viewport.Width - 50, 175);

            int rr = Color.CornflowerBlue.R;
            int gg = Color.CornflowerBlue.G;
            int bb = Color.CornflowerBlue.B;
            Color c = new Color(rr, gg, bb, 50);

            Colori = c;

            currentY = dummyRectangle.Y + 8;
        }


        /// <summary>Called when a character is entered on the keyboard</summary>
        /// <param name="character">Character that has been entered</param>
        private void charEntered(char character)
        {
            if (character == '\b')
            { // backspace
                if (this.userInputStringBuilder.Length > 0)
                {
                    this.userInputStringBuilder.Remove(this.userInputStringBuilder.Length - 1, 1);
                }
            }
            else if (character == (char)13)
            {
                SendCommand(this.userInputStringBuilder.ToString());
                this.userInputStringBuilder.Clear();

                currentY += int.Parse("" + _spriteFont.MeasureString(this.userInputStringBuilder.ToString()).Y);
                currentY += 16;
            }
            else
            {
                this.userInputStringBuilder.Append(character);
            }
        }


        /// <summary>Used to store the most recent state of the Game1 pad</summary>
        private ExtendedGamePadState state;
        /// <summary>Temporary string builder used for various purposes</summary>
        private StringBuilder tempStringBuilder = new StringBuilder();
        /// <summary>Contains the text the user has entered on the keyboard</summary>
        private StringBuilder userInputStringBuilder = new StringBuilder();

        /// <summary>Called when the player presses a button on the first Game1 pad</summary>
        /// <param name="buttons">Button(s) that have been pressed</param>
        private void Game1PadButtonPressed(Microsoft.Xna.Framework.Input.Buttons buttons)
        {

            // End the Game1 if the player has pressed the Back button
            if ((buttons & Microsoft.Xna.Framework.Input.Buttons.Back) != 0)
            {
                Game1.IsMouseVisible = false;
                Game1.StateManager.ActiveState = Game1.StateManager.GetState(typeof(PlayingState));
            }

        }



        public override void LoadContent()
        {
            _spriteFont = Game1.Content.Load<SpriteFont>("Fonts\\console");
            Vector2 textSize = _spriteFont.MeasureString(STARTTEXT);
            _startTextPosition = new Vector2((Game1.GraphicsDevice.Viewport.Width / 2.0f) - (textSize.X / 2), 20);
            this._spriteBatch = new SpriteBatch(Game.GraphicsDevice);

            dummyTexture = new Texture2D(Game1.GraphicsDevice, 1, 1);
            dummyTexture.SetData(new Color[] { Color.White });
        }
        
        public override void Update(GameTime Game1Time)
        {
            // Update the status of all input devices
            Game1.inputManager.Update();

            // Retrieve the state of the first connected Xbox 360 Game1 pad
            // (Hint: DirectInput devices are at index 5-8 if you want to try)
            IGamePad firstGame1Pad = Game1.inputManager.GetGamePad(ExtendedPlayerIndex.One);
            this.state = firstGame1Pad.GetExtendedState();
        }

        PlayerIndex _controllerIndex;
        public override void ProcessInput(GameTime Game1Time)
        {
            if (_game.InputState.IsKeyPressed(Keys.Escape, null, out _controllerIndex) ||
                _game.InputState.IsButtonPressed(Buttons.Back, null, out _controllerIndex))
            {
                Game1.IsMouseVisible = false;
                Game1.StateManager.ActiveState = Game1.StateManager.GetState(typeof(PlayingState));
            }
        }

        public void StorageDeviceSelected(IAsyncResult result)
        {
            _Game1.StorageDevice = StorageDevice.EndShowSelector(result); 

            //_Game1.StorageDevice = Guide.EndShowStorageDeviceSelector(result);
        }


        public void SendCommand(string cmd)
        {
            switch (cmd.Split(' ')[0])
            {

            }
        }

        Texture2D dummyTexture;
        Rectangle dummyRectangle;
        Color Colori;

        public override void Draw(GameTime Game1Time)
        {

            //Game1.GraphicsDevice.Clear(Color.CornflowerBlue);
            
            //Game1.GraphicsDevice.Clear(c);

            _spriteBatch.Begin();
            {
                _spriteBatch.Draw(txtr, new Rectangle(0, 0, Game1.GraphicsDevice.Viewport.Width, Game1.GraphicsDevice.Viewport.Height), Color.White);
                _spriteBatch.Draw(dummyTexture, dummyRectangle, Colori);
                // Print out the state of the Game1 pad
                //printGame1PadState();

                // Display the text the user has entered so far
                printKeyboardInput();


            }
            _spriteBatch.End();
        }

        int currentY = -1000;

        private void printKeyboardInput()
        {
            _spriteBatch.DrawString(
              _spriteFont, ">", new Vector2(50, currentY), Color.LightGreen
            );

            Vector2 size = _spriteFont.MeasureString("> ");
            try
            {
                _spriteBatch.DrawString(
                  _spriteFont, this.userInputStringBuilder,
                  new Vector2(50 + size.X, currentY), Color.LightGreen
                );
            }
            catch (Exception)
            {
                return;
            }
        }

        /// <summary>Displays the current state of the Game1 pad</summary>
        private void printGame1PadState()
        {

            // Device name
            {
                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat(
                  "Device: {0}",
                  Game1.inputManager.GetGamePad(ExtendedPlayerIndex.One).Name
                );
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 50), Color.Yellow
                );
            }

            // Axes
            {
                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat("Provided axes: {0}", state.AvailableAxes);
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 100), Color.White
                );

                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                foreach (ExtendedAxes axis in EnumHelper.GetValues<ExtendedAxes>())
                {
                    if ((state.AvailableAxes & axis) == axis)
                    {
                        tempStringBuilder.AppendFormat("{0}:{1} ", axis, state.GetAxis(axis));
                    }
                }
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 125), Color.White
                );
            }

            // Axes
            {
                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat("Provided sliders: {0}", state.AvailableSliders);
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 175), Color.White
                );

                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                foreach (ExtendedSliders slider in EnumHelper.GetValues<ExtendedSliders>())
                {
                    if ((state.AvailableSliders & slider) == slider)
                    {
                        tempStringBuilder.AppendFormat("{0}:{1} ", slider, state.GetSlider(slider));
                    }
                }
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 200), Color.White
                );
            }

            // Buttons
            {
                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat("Number of buttons: {0}", state.ButtonCount);
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 250), Color.White
                );

                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                for (int index = 0; index < state.ButtonCount; ++index)
                {
                    if (state.IsButtonDown(index))
                    {
                        tempStringBuilder.Append('X');
                    }
                    else
                    {
                        tempStringBuilder.Append('.');
                    }
                }
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 275), Color.White
                );
            }

            // PoVs
            {
                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat(
                  "Number of Point-of-View hats: {0}", state.PovCount
                );
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 325), Color.White
                );

                tempStringBuilder.Remove(0, tempStringBuilder.Length);
                tempStringBuilder.AppendFormat(
                  "Pov1:{0} Pov2:{1} Pov3:{2} Pov4:{3}",
                  state.Pov1, state.Pov2, state.Pov3, state.Pov4
                );
                spriteBatch.DrawString(
                  _spriteFont, tempStringBuilder, new Vector2(50, 350), Color.White
                );
            }

        }

        void b_Click(object sender, TomShane.Neoforce.Controls.EventArgs e)
        {
            Game1.Exit();
        }

        /// <summary>Batches sprites and text for efficient rendering</summary>
        private SpriteBatch spriteBatch;
    }
}
*/